package service

import (
	"stock-analyzer/internal/calculator"
	"stock-analyzer/internal/database"
	"stock-analyzer/internal/model"
	"time"
)

// FilterService 筛选服务
type FilterService struct {
	db *database.DB
}

// NewFilterService 创建新的筛选服务
func NewFilterService(db *database.DB) *FilterService {
	return &FilterService{db: db}
}

// FilterStocks 筛选股票
func (s *FilterService) FilterStocks(condition model.FilterCondition) ([]model.StockResult, error) {
	// 获取所有股票代码
	stockCodes, err := s.db.GetAllStockCodes()
	if err != nil {
		return nil, err
	}

	var results []model.StockResult

	for _, stockCode := range stockCodes {
		result, err := s.filterSingleStock(stockCode, condition.StartDate, condition.EndDate, condition)
		if err != nil {
			continue // 跳过错误股票，继续处理其他
		}

		if result.Passed {
			results = append(results, result)
		}
	}

	return results, nil
}

// filterSingleStock 筛选单个股票
func (s *FilterService) filterSingleStock(stockCode string, startDate, endDate time.Time, condition model.FilterCondition) (model.StockResult, error) {
	// 获取股票数据
	data, err := s.db.GetStockDataByTimeRange(stockCode, startDate, endDate)
	if err != nil {
		return model.StockResult{}, err
	}

	if len(data) == 0 {
		return model.StockResult{StockCode: stockCode, Passed: false}, nil
	}

	result := model.StockResult{
		StockCode: stockCode,
		Passed:    true, // 默认通过，后续检查条件
	}

	// 计算最大回撤
	result.MaxDrawdown = calculator.CalculateMaxDrawdown(data)

	// 检查回撤条件
	if condition.MaxDrawdown != nil && result.MaxDrawdown > *condition.MaxDrawdown {
		result.Passed = false
		return result, nil
	}

	// 检查窗口涨跌幅条件
	for _, rule := range condition.WindowChanges {
		// 计算该窗口的涨跌幅
		change, ok := calculator.CalculateWindowChange(data, rule.Window)
		if !ok {
			result.Passed = false
			break
		}

		// 记录实际涨跌幅
		result.WindowChanges = append(result.WindowChanges, model.WindowChange{
			Window: rule.Window,
			Change: change,
		})

		// 检查条件
		if !calculator.CheckWindowCondition(change, rule) {
			result.Passed = false
			break
		}
	}

	return result, nil
}

// GetStockData 获取股票数据（用于测试和调试）
func (s *FilterService) GetStockData(stockCode string, startDate, endDate time.Time) ([]model.StockData, error) {
	return s.db.GetStockDataByTimeRange(stockCode, startDate, endDate)
}
